package dataDraw.classDiagramDraw;

import data.DataVector;
import data.Position;
import data.classDiagram.*;
import dataDraw.Constants;
import dataDraw.TextDraw;

import java.awt.*;

/**
 * User: Szymon Kudzia
 * Date: 22.04.13
 * Time: 15:59
 */
public class BasicEntityDraw implements EntityDraw {
	protected TextDraw textDraw;
	protected Graphics graphics;

	public void draw(Entity entity, Graphics graphics) {
		this.graphics = graphics;
		textDraw.setGraphics(graphics);

		graphics.setColor(Color.black);

		Position current = entity.getPosition();
		current.clear();

		Position margin = new Position();
		margin.setHeight(Constants.MARGIN);
		updatePosition(current, margin);

		drawEntityName(entity, current);

		updatePosition(current, margin);
		int height_after_name = current.getHeight();
		updatePosition(current, margin);

		for (Member member : entity.getMembers()) {
			drawMember(member, current);
		}
		updatePosition(current, margin);
		int height_after_members = current.getHeight();
		updatePosition(current, margin);

		for (Method method : entity.getMethods()) {
			drawMethod(method, current);
		}
		updatePosition(current, margin);
		int height_after_methods = current.getHeight();



		if (entity instanceof ClassEntity) {
			ClassEntity cEntity = (ClassEntity) entity;
			if (!cEntity.getTriggers().isEmpty()) {
				updatePosition(current, margin);
				for (Trigger trigger : cEntity.getTriggers()) {
					drawTrigger(trigger, current);
				}
				updatePosition(current, margin);
				graphics.drawRect(current.getX(), current.getY(), current.getWidth(), current.getHeight());
			}
		}

		graphics.drawRect(current.getX(), current.getY(), current.getWidth(), height_after_name);
		graphics.drawRect(current.getX(), current.getY(), current.getWidth(), height_after_members);
		graphics.drawRect(current.getX(), current.getY(), current.getWidth(), height_after_methods);

		if (entity == DataVector.getInstance().getActiveEntity()) {
			drawEnvelope(current);
		}
	}

	private void drawEntityName(Entity entity, Position base) {
		if (entity instanceof ClassEntity) {
			textDraw.drawString(entity.getName(), base, true, false);
		}
		else if (entity instanceof InterfaceEntity) {
			textDraw.drawString(entity.getName(), base, true, true);
		}
		else {
			textDraw.drawString(entity.getName(), base);
		}


		Position p = new Position();
		p.setHeight(graphics.getFontMetrics().getHeight());
		p.setWidth(graphics.getFontMetrics().stringWidth(entity.getName()) + 2 * Constants.MARGIN);

		updatePosition(base, p);
	}

	private void drawMember(Member member, Position base) {
		Position current = member.getPosition();
		current.clear();

		current.setX(base.getX());
		current.setY(base.getSecondY());

		if (member.isStatic()) {
			textDraw.drawString(member.toString(), current, false, true);
		} else {
			textDraw.drawString(member.toString(), current);
		}

		updatePosition(base, current);

		Position p = new Position();
		p.setHeight(graphics.getFontMetrics().getHeight());
		p.setWidth(graphics.getFontMetrics().stringWidth(member.toString()) + 2 * Constants.MARGIN);

		updatePosition(base, p);
	}

	private void drawMethod(Method method, Position base) {
		Position current = method.getPosition();
		current.clear();

		current.setX(base.getX());
		current.setY(base.getSecondY());

		if (method.isStatic()) {
			textDraw.drawString(method.toString(), current, false, true);
		} else {
			textDraw.drawString(method.toString(), current);
		}

		Position p = new Position();
		p.setHeight(graphics.getFontMetrics().getHeight());
		p.setWidth(graphics.getFontMetrics().stringWidth(method.toString()) + 2 * Constants.MARGIN);

		updatePosition(base, p);
	}

	private void drawEnvelope(Position current) {
		graphics.setColor(Color.red);

		graphics.drawRect(current.getFirstX() - Constants.MARGIN,
				current.getFirstY() - Constants.MARGIN,
				current.getWidth() + 2 * Constants.MARGIN,
				current.getHeight() + 2 * Constants.MARGIN);

		graphics.setColor(Color.black);
	}


	private void drawTrigger(Trigger trigger, Position base) {
		Position current = trigger.getPosition();
		current.clear();

		current.setX(base.getX());
		current.setY(base.getSecondY());

		textDraw.drawString(trigger.toString(), current);

        Position p = new Position();
        p.setHeight(graphics.getFontMetrics().getHeight());
        p.setWidth(graphics.getFontMetrics().stringWidth(trigger.toString()) + 2 * Constants.MARGIN);

        updatePosition(base, p);
	}

	private void updatePosition(Position current, Position p) {
		current.setHeight(current.getHeight() + p.getHeight());

		if (p.getWidth() > current.getWidth()) {
			current.setWidth(p.getWidth());
		}
	}

	public void setTextDraw(TextDraw textDraw) {
		this.textDraw = textDraw;
	}
}
